home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 25 / AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso / Updates / PowerPC / jpeg2ps / readjpeg.c < prev    next >
C/C++ Source or Header  |  2000-05-16  |  10KB  |  324 lines

  1. /* ------------------------- readjpeg.c ------------------------- */
  2. #include <stdio.h>
  3. #include <string.h>
  4.  
  5. #ifndef DOS
  6. #include <unistd.h>
  7. #endif
  8.  
  9. #include "psimage.h"
  10.  
  11. /* The following enum is stolen from the IJG JPEG library
  12.  * Comments added by tm
  13.  * This table contains far too many names since jpeg2ps
  14.  * is rather simple-minded about markers
  15.  */
  16.  
  17. extern BOOL quiet;
  18.  
  19. typedef enum {        /* JPEG marker codes            */
  20.   M_SOF0  = 0xc0,    /* baseline DCT                */
  21.   M_SOF1  = 0xc1,    /* extended sequential DCT        */
  22.   M_SOF2  = 0xc2,    /* progressive DCT            */
  23.   M_SOF3  = 0xc3,    /* lossless (sequential)        */
  24.   
  25.   M_SOF5  = 0xc5,    /* differential sequential DCT        */
  26.   M_SOF6  = 0xc6,    /* differential progressive DCT        */
  27.   M_SOF7  = 0xc7,    /* differential lossless        */
  28.   
  29.   M_JPG   = 0xc8,    /* JPEG extensions            */
  30.   M_SOF9  = 0xc9,    /* extended sequential DCT        */
  31.   M_SOF10 = 0xca,    /* progressive DCT            */
  32.   M_SOF11 = 0xcb,    /* lossless (sequential)        */
  33.   
  34.   M_SOF13 = 0xcd,    /* differential sequential DCT        */
  35.   M_SOF14 = 0xce,    /* differential progressive DCT        */
  36.   M_SOF15 = 0xcf,    /* differential lossless        */
  37.   
  38.   M_DHT   = 0xc4,    /* define Huffman tables        */
  39.   
  40.   M_DAC   = 0xcc,    /* define arithmetic conditioning table    */
  41.   
  42.   M_RST0  = 0xd0,    /* restart                */
  43.   M_RST1  = 0xd1,    /* restart                */
  44.   M_RST2  = 0xd2,    /* restart                */
  45.   M_RST3  = 0xd3,    /* restart                */
  46.   M_RST4  = 0xd4,    /* restart                */
  47.   M_RST5  = 0xd5,    /* restart                */
  48.   M_RST6  = 0xd6,    /* restart                */
  49.   M_RST7  = 0xd7,    /* restart                */
  50.   
  51.   M_SOI   = 0xd8,    /* start of image            */
  52.   M_EOI   = 0xd9,    /* end of image                */
  53.   M_SOS   = 0xda,    /* start of scan            */
  54.   M_DQT   = 0xdb,    /* define quantization tables        */
  55.   M_DNL   = 0xdc,    /* define number of lines        */
  56.   M_DRI   = 0xdd,    /* define restart interval        */
  57.   M_DHP   = 0xde,    /* define hierarchical progression    */
  58.   M_EXP   = 0xdf,    /* expand reference image(s)        */
  59.   
  60.   M_APP0  = 0xe0,    /* application marker, used for JFIF    */
  61.   M_APP1  = 0xe1,    /* application marker            */
  62.   M_APP2  = 0xe2,    /* application marker            */
  63.   M_APP3  = 0xe3,    /* application marker            */
  64.   M_APP4  = 0xe4,    /* application marker            */
  65.   M_APP5  = 0xe5,    /* application marker            */
  66.   M_APP6  = 0xe6,    /* application marker            */
  67.   M_APP7  = 0xe7,    /* application marker            */
  68.   M_APP8  = 0xe8,    /* application marker            */
  69.   M_APP9  = 0xe9,    /* application marker            */
  70.   M_APP10 = 0xea,    /* application marker            */
  71.   M_APP11 = 0xeb,    /* application marker            */
  72.   M_APP12 = 0xec,    /* application marker            */
  73.   M_APP13 = 0xed,    /* application marker            */
  74.   M_APP14 = 0xee,    /* application marker, used by Adobe    */
  75.   M_APP15 = 0xef,    /* application marker            */
  76.   
  77.   M_JPG0  = 0xf0,    /* reserved for JPEG extensions        */
  78.   M_JPG13 = 0xfd,    /* reserved for JPEG extensions        */
  79.   M_COM   = 0xfe,    /* comment                */
  80.   
  81.   M_TEM   = 0x01,    /* temporary use            */
  82.  
  83.   M_ERROR = 0x100    /* dummy marker, internal use only    */
  84. } JPEG_MARKER;
  85.  
  86. /*
  87.  * The following routine used to be a macro in its first incarnation:
  88.  *  #define get_2bytes(fp) ((unsigned int) (getc(fp) << 8) + getc(fp))
  89.  * However, this is bad programming since C doesn't guarantee
  90.  * the evaluation order of the getc() calls! As suggested by
  91.  * Murphy's law, there are indeed compilers which produce the wrong
  92.  * order of the getc() calls, e.g. the Metrowerks C compilers for BeOS
  93.  * and Macintosh.
  94.  * Since there are only few calls we don't care about the performance 
  95.  * penalty and use a simplistic C function.
  96.  */
  97.  
  98. /* read two byte parameter, MSB first */
  99. static unsigned int
  100. get_2bytes(FILE *fp)
  101. {
  102.     unsigned int val;
  103.     val = getc(fp) << 8;
  104.     val += getc(fp);
  105.     return val;
  106. }
  107.  
  108. static int 
  109. next_marker P1(FILE *, fp)
  110. { /* look for next JPEG Marker  */
  111.   int c, nbytes = 0;
  112.  
  113.   if (feof(fp))
  114.     return M_ERROR;                 /* dummy marker               */
  115.  
  116.   do {
  117.     do {                            /* skip to FF           */
  118.       nbytes++;
  119.       c = getc(fp);
  120.     } while (c != 0xFF);
  121.     do {                            /* skip repeated FFs        */
  122.       c = getc(fp);
  123.     } while (c == 0xFF);
  124.   } while (c == 0);                 /* repeat if FF/00                 */
  125.  
  126.   return c;
  127. }
  128.  
  129. /* analyze JPEG marker */
  130. BOOL AnalyzeJPEG P1(imagedata *, image) {
  131.   int b, c, unit;
  132.   unsigned long i, length = 0;
  133. #define APP_MAX 255
  134.   unsigned char appstring[APP_MAX];
  135.   BOOL SOF_done = FALSE;
  136.  
  137.   /* Tommy's special trick for Macintosh JPEGs: simply skip some  */
  138.   /* hundred bytes at the beginning of the file!          */
  139.   do {
  140.     do {                            /* skip if not FF           */
  141.       c = getc(image->fp);
  142.     } while (!feof(image->fp) && c != 0xFF);
  143.  
  144.     do {                            /* skip repeated FFs       */
  145.       c = getc(image->fp);
  146.     } while (c == 0xFF);
  147.  
  148.     /* remember start position */
  149.     if ((image->startpos = ftell(image->fp)) < 0L) {
  150.       fprintf(stderr, "Error: internal error in ftell()!\n");
  151.       return FALSE;
  152.     }
  153.     image->startpos -= 2;           /* subtract marker length     */
  154.  
  155.     if (c == M_SOI) {
  156.       fseek(image->fp, image->startpos, SEEK_SET);
  157.       break;
  158.     }
  159.   } while (!feof(image->fp));
  160.  
  161.   if (feof(image->fp)) {
  162.     fprintf(stderr, "Error: SOI marker not found!\n");
  163.     return FALSE;
  164.   }
  165.  
  166.   if (image->startpos > 0L && !quiet) {
  167.     fprintf(stderr, "Note: skipped %ld bytes ", image->startpos);
  168.     fprintf(stderr, "Probably Macintosh JPEG file?\n");
  169.   }
  170.  
  171.   /* process JPEG markers */
  172.   while (!SOF_done && (c = next_marker(image->fp)) != M_EOI) {
  173.     switch (c) {
  174.       case M_ERROR:
  175.     fprintf(stderr, "Error: unexpected end of JPEG file!\n");
  176.     return FALSE;
  177.  
  178.       /* The following are not officially supported in PostScript level 2 */
  179.       case M_SOF2:
  180.       case M_SOF3:
  181.       case M_SOF5:
  182.       case M_SOF6:
  183.       case M_SOF7:
  184.       case M_SOF9:
  185.       case M_SOF10:
  186.       case M_SOF11:
  187.       case M_SOF13:
  188.       case M_SOF14:
  189.       case M_SOF15:
  190.     fprintf(stderr, 
  191.          "Warning: JPEG file uses compression method %X - proceeding anyway.\n",
  192.           c);
  193.         fprintf(stderr, 
  194.         "PostScript output does not work on all PS interpreters!\n");
  195.     /* FALLTHROUGH */
  196.  
  197.       case M_SOF0:
  198.       case M_SOF1:
  199.     length = get_2bytes(image->fp);    /* read segment length  */
  200.  
  201.     image->bits_per_component = getc(image->fp);
  202.     image->height             = get_2bytes(image->fp);
  203.     image->width              = get_2bytes(image->fp);
  204.     image->components         = getc(image->fp);
  205.  
  206.     SOF_done = TRUE;
  207.     break;
  208.  
  209.       case M_APP0:        /* check for JFIF marker with resolution */
  210.     length = get_2bytes(image->fp);
  211.  
  212.     for (i = 0; i < length-2; i++) {    /* get contents of marker */
  213.       b = getc(image->fp);
  214.       if (i < APP_MAX)            /* store marker in appstring */
  215.         appstring[i] = b;
  216.     }
  217.  
  218.     /* Check for JFIF application marker and read density values
  219.      * per JFIF spec version 1.02.
  220.      * We only check X resolution, assuming X and Y resolution are equal.
  221.      * Use values only if resolution not preset by user or to be ignored.
  222.      */
  223.  
  224. #define ASPECT_RATIO    0    /* JFIF unit byte: aspect ratio only */
  225. #define DOTS_PER_INCH    1    /* JFIF unit byte: dots per inch     */
  226. #define DOTS_PER_CM    2    /* JFIF unit byte: dots per cm       */
  227.  
  228.     if (image->dpi == DPI_USE_FILE && length >= 14 &&
  229.         !strncmp((const char *)appstring, "JFIF", 4)) {
  230.       unit = appstring[7];                /* resolution unit */
  231.                           /* resolution value */
  232.       image->dpi = (float) ((appstring[8]<<8) + appstring[9]);
  233.  
  234.       if (image->dpi == 0.0) {
  235.         image->dpi = DPI_USE_FILE;
  236.         break;
  237.       }
  238.  
  239.       switch (unit) {
  240.         /* tell the caller we didn't find a resolution value */
  241.         case ASPECT_RATIO:
  242.           image->dpi = DPI_USE_FILE;
  243.           break;
  244.  
  245.         case DOTS_PER_INCH:
  246.           break;
  247.  
  248.         case DOTS_PER_CM:
  249.           image->dpi *= (float) 2.54;
  250.           break;
  251.  
  252.         default:                /* unknown ==> ignore */
  253.           fprintf(stderr, 
  254.         "Warning: JPEG file contains unknown JFIF resolution unit - ignored!\n");
  255.           image->dpi = DPI_IGNORE;
  256.           break;
  257.       }
  258.     }
  259.         break;
  260.  
  261.       case M_APP14:                /* check for Adobe marker */
  262.     length = get_2bytes(image->fp);
  263.  
  264.     for (i = 0; i < length-2; i++) {    /* get contents of marker */
  265.       b = getc(image->fp);
  266.       if (i < APP_MAX)            /* store marker in appstring */
  267.         appstring[i] = b;
  268.     }
  269.  
  270.     /* Check for Adobe application marker. It is known (per Adobe's TN5116)
  271.      * to con